import time
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from A3mall_pytest.pytest_a3mall_db import Mydb
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from loguru import logger

logger.add('./A3mall_pytest/pytest_yw1.log', level='DEBUG')


# 测试固件：浏览器初始化
# 当你使用这个夹具时，pytest 会自动为每个参数值生成一个新的测试函数，每个测试函数都会接收到相应的参数值(每个用例执行三次：三个浏览器个执行一次)
# @pytest.fixture(scope="function", params=["chromium", "firefox", "webkit"])
@pytest.fixture(scope="function")
def get_driver():
    driver = webdriver.Firefox()
    driver.maximize_window()
    driver.get('http://10.59.9.14:7003/')
    # 连接数据库
    db = Mydb('10.59.9.14', 'root', 'yidong666', 'a3mall', '3306')
    yield driver, db
    # 关闭数据库连接
    db.close()
    time.sleep(10)
    driver.quit()
class Test_a3mall_yw1():

    def setup(self):
        print('start case 01')
        logger.info('start case 01')

    def teardown(self):
        print('case 01 end')
        logger.info('case 01 end')

    userprice = None
    @pytest.mark.smoke
    def test_a3mall_yw1_01(self, get_driver):
        try:
            self.driver, self.db = get_driver
            # 1、点击登录
            self.driver.find_element(By.XPATH, '//a[@href="/home/login.html"]').click()
            # 断言1：会员登录
            dy1 = self.driver.find_element(By.CLASS_NAME, 'reg-new').text
            print(f'dy1:{dy1}')
            assert '会员登录' == dy1, "字符串不相等"
            # 2、输入用户名
            self.driver.find_element(By.NAME, 'username').send_keys('15985645484')
            # 3、输入密码
            self.driver.find_element(By.NAME, 'password').send_keys('123456')
            # 4、勾选记住密码
            self.driver.find_element(By.CSS_SELECTOR, '#theForm > div.agree-clause > span > label > input').click()
            # 强制等待10秒，输入验证码
            time.sleep(10)
            # 5、点击登录按钮
            self.driver.find_element(By.CLASS_NAME, 'finish-btn').click()
            time.sleep(5)
            # 断言2：欢迎回来，小高4
            dy2 = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div[1]/div[2]/div[2]/ul/li[1]').text
            print(f'dy2:{dy2}')
            assert '欢迎回来' in dy2, "欢迎回来不在dy2中"
            price = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div[1]/div[2]/div[2]/ul/li[4]/span').text
            price1 = str(price).split('¥ ')
            print(f"用户总金额:{price1[1]}")
            Test_a3mall_yw1.userprice = float(price1[1])
        except Exception as e:
            # time.strftime：这是Python的time模块中的一个函数，用于将时间格式化为指定的字符串格式
            # time.localtime()：获取当前本地时间
            t = time.strftime('%Y%m%d%H%M%S', time.localtime())
            # save_screenshot：这是Webdriver的一个方法，用于保存当前浏览器窗口的截图
            self.driver.save_screenshot('E:\zhuangaoer_pyCharm\zhuangaowuday1\A3mall_pytest/' + t + 'pytest_yw1.png')
            print(f'异常信息：{e}')
            raise

    def test_a3mall_yw1_02(self, get_driver):
        logger.info('start case 01')
        try:
            # 前置条件 ：账号已登录
            self.test_a3mall_yw1_01(get_driver)
            time.sleep(1)
            # 1、输入关键字搜索
            ss = self.driver.find_element(By.TAG_NAME, 'input')
            # 鼠标右击事件
            ActionChains(self.driver).context_click(ss).perform()
            time.sleep(2)
            # 鼠标释放事件
            ActionChains(self.driver).release(ss).perform()
            time.sleep(2)
            # 键盘输入事件
            ss.send_keys('水瓶座')
            time.sleep(2)
            # 键盘退格事件
            ss.send_keys(Keys.BACKSPACE)
            time.sleep(1)
            # 键盘回车事件
            ss.send_keys(Keys.ENTER)
            time.sleep(3)
            # 浏览器返回事件
            self.driver.back()
            time.sleep(2)
            # 浏览器前进事件
            self.driver.forward()
            time.sleep(2)
            # 浏览器刷新事件
            self.driver.refresh()
            time.sleep(2)
            # 2、双击要下单的商品
            sp1 = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div[2]/div[1]/ul/li/div[1]/span/a/img')
            # 鼠标双击事件
            ActionChains(self.driver).double_click(sp1).perform()
            # 断言3：断言商品详情的商品名称：性能测试-水瓶
            # 隐式等待
            self.driver.implicitly_wait(5)
            dy3 = self.driver.find_element(By.XPATH, '//*[@id="goodsForm"]/div/div[1]/span').text
            print(f'dy3:{dy3}')
            assert '性能测试-水瓶' == dy3
            # 3、选择购买的商品数量
            num = self.driver.find_element(By.XPATH,
                                           '/html/body/div[5]/div/div[2]/form/div/div[4]/div[1]/div[1]/div[1]/input')
            num.clear()
            time.sleep(1)
            num.send_keys('2')
            # 4、点击立即购买
            self.driver.find_element(By.ID, 'buy-cart').click()
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言4：断言进入确认订单页面
            dy4 = self.driver.find_element(By.XPATH, '/html/body/div[4]/div[1]/a[2]').text
            print(f'dy4:{dy4}')
            assert '确认订单' == dy4
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言5：断言收货地址信息包含：15985645484
            dy5 = self.driver.find_element(By.XPATH, '//*[@id="theForm"]/div[1]/div[2]/div/label').text
            print(f'dy5:{dy5}')
            assert '15985645484' in dy5
            # 5、点击下一步
            self.driver.find_element(By.ID, 'order-button').click()
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言6：断言进入订单提交页面
            dy6 = self.driver.find_element(By.XPATH, '/html/body/div[4]/div[1]/a[2]').text
            print(f'dy6:{dy6}')
            assert '订单完成' == dy6
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言7：断言提交订单成功
            dy7 = self.driver.find_element(By.XPATH, '/html/body/div[4]/div[3]/span').text
            print(f'dy7:{dy7}')
            assert '支付成功' in dy7
            # 6、点击查看订单
            self.driver.find_element(By.XPATH, '/html/body/div[4]/div[3]/p/a').click()
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言8：断言进入订单详情页面
            dy8 = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div/div[1]/span').text
            print(f'dy8:{dy8}')
            assert '我的订单' == dy8
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言9：断言生成了订单号
            dy9 = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div/div[2]/table[2]/tbody/tr[2]/td[2]').text
            print(f'day9:{dy9}')
            assert dy9
            # 隐式等待
            self.driver.implicitly_wait(5)
            # 断言10：数据库断言：用户总金额-订单支付金额=用户余额
            # 订单支付金额
            yf_price = self.driver.find_element(By.XPATH, '/html/body/div[5]/div[2]/div/div[5]/div/div/div[2]/span').text
            orderprice = float(str(yf_price).split('￥￥')[1])
            print(f"订单支付金额：{orderprice}")
            # 用户余额
            amount = self.db.seatch(f"select amount from mall_users where mobile = '{15985645484}'")[0][0]
            print(f"用户余额：{amount}")
            assert str(Test_a3mall_yw1.userprice - orderprice) == str(amount)
        except Exception as e:
            # time.strftime：这是Python的time模块中的一个函数，用于将时间格式化为指定的字符串格式
            # time.localtime()：获取当前本地时间
            t = time.strftime('%Y%m%d%H%M%S', time.localtime())
            # save_screenshot：这是Webdriver的一个方法，用于保存当前浏览器窗口的截图
            self.driver.save_screenshot('E:\zhuangaoer_pyCharm\zhuangaowuday1\A3mall_pytest/' + t + 'pytest_yw1.png')
            print(f'异常信息：{e}')
            raise

        logger.info('case 01 end')



if __name__ == '__main__':
    # 命令行执行： 1、生成allure报告：pytest ./A3mall_pytest/pytest_yw1_test.py --alluredir=./A3mall_pytest/测试报告
    # pytest --html=./A3mall_pytest/pytest_yw1.html ./A3mall_pytest/pytest_yw1_test.py
    # 2、生成pytest-html报告：pytest --html=a3mall_yw01_report.html ./A3mall_pytest/pytest_yw1_test.py

    # pytest.main(["--html=./A3mall_pytest/A3mall_yw1.html", './A3mall_pytest/pytest_yw1_test.py'])
    pytest.main(['pytest_yw1_test.py'])
    # pytest.main()
    # 生成 HTML 测试报告（文件名为 report.html） --self-contained-html：将 CSS 和 JS 内嵌到报告中，便于单文件分享 -v：这是一个简写参数，等同于 --verbose。它使 pytest 输出更详细的信息，包括每个测试函数的名称和详细的测试结果。
    # pytest.main(['./', "-v", "--html=A3mall_yw1.html", "--self-contained-html", 'pytest_yw1_test.py'])
    #   ./表去哪找用例文件（以test开头的py文件）   -s表：将print语句输出到控制台  --html表：生成报告（前提：安装pytest-html模块）  ./report.html表：生成报告的文件路径
    # pytest.main(['./', '-s', '--html=./report.html'])
    # 三种执行方式演示：
    # 1. 默认执行（Chromium）
    # pytest.main(["-v", "--html=./ay_rkao/test_day14_01/report.html"])

    # 2. 指定浏览器执行
    # pytest.main(["-v", "--html=report.html", "--browser=firefox"])

    # 3. Headless模式执行
    # os.environ["HEADLESS"] = "True"
    # pytest.main(["-v", "--html=report.html"])



